package roborally.filters;

import roborally.model.Element;
import roborally.model.Position;

/**
 * A class to check whether a given object satisfies the condition
 * of lying in a given subrange of a board.
 * 
 * @invar	The given top-left position should be a valid position.	
 * @invar	The given bottom-right position should be a valid position.
 * 
 * @version 1.0
 * @author  Pieter Robberechts	(1e Bach Informatica)
 * @author	Jeroen Sanders		(1e Bach Informatica)
 */
public class IsInSubrangeEvaluator extends ConditionEvaluator {

	/**
	 * Initialize this new is-in-subrange evaluator with a top-left position and
	 * a bottom-right position.
	 * 
	 * @param 	topLeft
	 * 			The top-left position of the subrange.
	 * @param 	bottomRight
	 * 			The bottom-right position of the subrange.
	 * @pre		The top-left position should be a valid position.
	 * @pre		The bottom-right position should be a valid position.
	 * @post	The given top-left position is set as the top-left position
	 * 			for this is-in-subrange evaluator.
	 * @post	The given bottom-right position is set as the bottom-right position
	 * 			for this is-in-subrange evaluator.
	 */
	public IsInSubrangeEvaluator(Position topLeft, Position bottomRight) {
		assert canHaveAsTopLeftPosition(topLeft);
		assert canHaveAsBottomRightPosition(bottomRight);
		this.topLeftPosition = topLeft;
		this.bottomRightPosition = bottomRight;
	}
	
	/**
	 * Return the top-left position of the subrange involved
	 * in this is-in-subrange evaluator.
	 */
	public Position getTopLeftPosition() {
		return topLeftPosition;
	}
	
	/**
	 * Check whether the given position is a valid top-left position
	 * for this is-in-subrange evaluator.
	 * 
	 * @param 	position
	 * 			The position to check for whether it is a valid top-left position.
	 * @return	Return true if and only if the given position is effective; 
	 * 			else return false.
	 */
	public boolean canHaveAsTopLeftPosition(Position position) {
		return (position != null);
	}

	/**
	 * Variable registering the top-left position of the subrange involved
	 * in this is-in-subrange evaluator.
	 */
	private final Position topLeftPosition;
	
	/**
	 * Return the bottom-right position of the subrange involved
	 * in this is-in-subrange evaluator.
	 */
	public Position getBottomRightPosition() {
		return bottomRightPosition;
	}
	
	/**
	 * Check whether the given position is a valid bottom-right position
	 * for this is-in-subrange evaluator.
	 * 
	 * @param 	position
	 * 			The position to check for whether it is a valid bottom-right position.
	 * @return	Return true if and only if the given position is effective; 
	 * 			else return false.
	 */
	public boolean canHaveAsBottomRightPosition(Position position) {
		return (position != null);
	}

	/**
	 * Variable registering the bottom-right position of the subrange involved
	 * in this is-in-subrange evaluator.
	 */
	private final Position bottomRightPosition;
	
	/**
	 * Check whether the given object satisfies this is-in-subrange condition.
	 * 
	 * @return	Return false if the given object hasn't got a position.
	 * @return	Return true if and only if the given object has a position 
	 * 			which is in the subrange associated with this is-in-subrange 
	 * 			evaluator; else return false.
	 */
	@Override
	public boolean isTrue(Element object) {
		if(object == null)
			return false;
		if(object.getPosition() == null)
			return false;
		return object.getPosition().isInRange(getTopLeftPosition(), getBottomRightPosition());
	}

}
